<template>
  <section class="tool-container">
    <div class="tool-left">
      <div class="tool-style">
        <div class="tool-select" :title="theme" @click="showThemeDialog = true">{{ theme }}</div>
      </div>
      <div class="tool-mode">
        <div class="tool-select" :title="mode" @click="showModeDialog = true">{{ mode }}</div>
      </div>
    </div>
    <div class="tool-right">
      <div class="share btn" v-if="!props.hideShareBtn" @click="emit('share')"><i class="iconfont icon-share"></i>share
      </div>
      <div class="share btn" v-if="props.enableEdit" @click="emit('update')"><i class="iconfont icon-editor"></i>update
      </div>
      <div @click="exportImg" class="export btn"><i class="iconfont icon-Exportservices"></i>export</div>
    </div>
  </section>
  <app-dialog
    width="750px"
    title="选择主题"
    v-model:show="showThemeDialog"
  >
    <div class="theme-dialog">
      <template v-if="themeHistories.length">
        <app-title>历史记录</app-title>
        <div class="item-box">
          <div class="item"
               @click="changeTheme(item)"
               :class="{on:theme === item}"
               :title="item" :key="item"
               v-for="item in themeHistories">
            {{ item }}
          </div>
        </div>
      </template>

      <app-title>所有主题</app-title>
      <div class="item-box">
        <div class="item" @click="changeTheme(item)" :class="{on:theme === item}" :title="item" :key="item"
             v-for="item in themes">
          {{ item }}
        </div>
      </div>
    </div>
  </app-dialog>
  <app-dialog
    width="750px"
    title="选择语言"
    v-model:show="showModeDialog"
  >
    <div class="theme-dialog">
      <template v-if="modeHistories.length">
        <app-title>历史记录</app-title>
        <div class="item-box">
          <div class="item"
               @click="changeMode(item)"
               :class="{on:mode === item.name}" :title="item.name"
               :key="item.name" v-for="item in modeHistories">
            {{ item.name }}
          </div>
        </div>
      </template>
      <app-title>所有语言</app-title>
      <div class="item-box">
        <div class="item" @click="changeMode(item)"
             :class="{on:mode === item.name}"
             :title="item.name" :key="item.name"
             v-for="item in LANGUAGES">
          {{ item.name }}
        </div>
      </div>
    </div>
  </app-dialog>
</template>

<script lang="ts" setup>
// import hljs from 'highlight.js'
// hljs.configure({
//   classPrefix: 'cm-'
// })
import html2canvas from 'html2canvas'
import {inject, nextTick, onMounted, ref, watch} from 'vue'
import * as Codemirror from 'codemirror'
import { CodemirrorInstance } from 'codemirror'
import { THEMES } from '@/components/global/CodeEditor/EditorTool/config'
import codeHistory from '@/hooks/codeHistory'

const parentInject = inject('codemirrorInstance') as { codemirrorInstance: CodemirrorInstance }

const { modeHistories, themeHistories, setHistoryMode, setHistoryTheme } = codeHistory()

const AUTO = {
  name: 'Auto',
  mode: 'auto'
}
const LANGUAGES = [
  // AUTO,
  ...Codemirror.modeInfo
]

interface Props {
  theme: string
  mode: string
  hideShareBtn: boolean
  enableEdit: boolean
}

const props = withDefaults(defineProps<Props>(),
  {
    theme: '',
    mode: '',
    hideShareBtn: false,
    enableEdit: false
  })

const showThemeDialog = ref(false)
const showModeDialog = ref(false)
const theme = ref('')
const mode = ref('')
const emit = defineEmits(['changeTheme', 'changeMode', 'share', 'update'])
const themes = THEMES

const changeMode = (language: any) => {
  showModeDialog.value = false
  if (!props.hideShareBtn){
    setHistoryMode(language)
  }
  if (language.name !== mode.value) {
    importMode(language)
  }
}

const changeTheme = (theme: any) => {
  showThemeDialog.value = false
  if (!props.hideShareBtn){
    setHistoryTheme(theme)
  }
  if (theme !== theme.value) {
    importTheme(theme)
  }
}

const importMode = (language: any) => {
  const { mime, mode } = language
  if (language.mode === 'vue') {
    parentInject.codemirrorInstance?.setOption('mode', mime || mode)
    emit('changeMode', language)
    return
  }
  if (language.mode === 'null') {
    parentInject.codemirrorInstance?.setOption('mode', 'null')
    emit('changeMode', language)
    return
  }
  import(/* @vite-ignore */'../../../../../node_modules/codemirror/mode/' + mode + '/' + mode + '.js').then(() => {
    emit('changeMode', language)
    nextTick(() => {
      parentInject.codemirrorInstance?.setOption('mode', mime || mode)
    })
  })
}
const importTheme = (theme: any) => {
  if (theme) {
    import(/* @vite-ignore */'../../../../../node_modules/codemirror/theme/' + theme + '.css')
    parentInject.codemirrorInstance?.setOption('theme', theme)
    emit('changeTheme', theme)
    showThemeDialog.value = false
  }
}


const getLanguagesByName = (name: string) => {
  return Codemirror.findModeByName(name)
}

onMounted(()=>{
  nextTick(()=>{
    theme.value = themeHistories.value[0] || 'darcula'
    importTheme(theme.value)
    mode.value = modeHistories.value[0]?.name || 'Java'
    const language = mode.value === 'Auto' ? AUTO : getLanguagesByName(mode.value)
    importMode(language)
  })
})

watch([() => props.theme, () => props.mode], (val, old) => {
  console.log(val)
  const [t, m] = val || ['', '']
  const [oldT, oldM] = old || ['', '']
  if (t && t !== oldT) {
    theme.value = t
    importTheme(t)
  }
  if (m && m !== oldM) {
    mode.value = m
    const language = m === 'Auto' ? AUTO : getLanguagesByName(m)
    importMode(language)
  }
}, {
  immediate: true
})

// watch([() => theme.value, () => mode.value], (val) => {
//   const [t, m] = val || ['', '']
//   if (t) {
//     importTheme(t)
//   }
//   if (m) {
//     const language = m === 'Auto' ? AUTO : getLanguagesByName(m)
//     importMode(language)
//   }
// }, {
//   immediate: true
// })


const exportImg = () => {
  html2canvas(parentInject.codemirrorInstance?.doc.cm.getWrapperElement(), {
    allowTaint: true,
    scale: 1,
    useCORS: true
  }).then(canvas => {
    const imgSrc = canvas.toDataURL('image/png', 1)
    let downloadElement = document.createElement('a')
    downloadElement.href = imgSrc
    downloadElement.download = `code.png` //下载后文件名
    document.body.appendChild(downloadElement)
    downloadElement.click() //点击下载
    document.body.removeChild(downloadElement) //下载完成移除元素
  })
}
</script>
<style scoped lang="scss">
@import "./index";
</style>
